package detect.parse.tree.token;

import java.util.*;

import util.FileManager;

public class SimpleTokenScanner {
	static HashMap<String,RawTokenType> rewordsMap=new  HashMap<String,RawTokenType>();
	static HashMap<String,RawTokenType> puncsMap=new  HashMap<String,RawTokenType>();
	public static void main(String[] args){
		String filePath="d:\\test.cpp";
		String str=FileManager.readStringFromFile(filePath);
		TokenList tokenList=getTokenList(new PositionString(str,0));
	}
	
	public static TokenList getTokenList(PositionString psStr){		
		List<Token> tokens=new ArrayList<Token>();
		String str=psStr.str;
		int pos=0;
		while(pos<str.length()){
			
			while(isBlank(str.charAt(pos))){
				pos++;
			}
			int cursor=pos;
			char curChar='0';
			while(true){
				curChar = str.charAt(cursor);
				if(!isLetter(curChar)){
					break;
				}
				cursor++;
				if(cursor>=str.length()){
					break;
				}
			}
			Token t=null;
			
			if(pos==cursor){
				t=new Token(str.substring(pos,cursor+1),pos);
				pos++;
			}
			else{
				t=new Token(str.substring(pos,cursor),pos);
				pos=cursor;
			}
			tokens.add(t);		
			
			//System.out.println(t);			
		}
		TokenList tokenList=attributeTokenList(psStr,tokens);
		return tokenList;
	}
	
	public static TokenList attributeTokenList(PositionString psStr,List<Token> tokens){
		initTokenMap();
		List<Token> atrTokenList=new ArrayList<Token>(tokens.size());
		for(int i=0;i<tokens.size();i++){
			Token curToken=tokens.get(i);
			if(isLetter(curToken.str.charAt(0))){
				RawTokenType type=rewordsMap.get(curToken.str);
				if(type!=null){
					curToken.rawType=type;
				}
				else{
					Token preToken=tokens.get(i-1);				
					if(i>0 && preToken.rawType==RawTokenType.IDENTIFIER){						
							preToken.rawType=RawTokenType.TYPE;
							curToken.rawType=RawTokenType.IDENTIFIER;
					}
					else{
						curToken.rawType=RawTokenType.IDENTIFIER;
					}
				}
			}
			else{
				RawTokenType type=puncsMap.get(curToken.str);
				if(type!=null){
					curToken.rawType=type;
				}
				else{
					curToken.rawType=RawTokenType.NEQ;
				}
			}
			atrTokenList.add(curToken);
		}
		return new TokenList(psStr,atrTokenList);
	}
	
	public static void initTokenMap(){
		for(int i=0;i<Token.reservedWords.length;i++){
			rewordsMap.put(Token.reservedWords[i],Token.reservedWordsType[i]);
		}
		
		for(int i=0;i<Token.punctuations.length;i++){
			puncsMap.put(Token.punctuations[i],Token.punctuationsType[i]);
		}
	}
	
	public static boolean isLetter(char ch){
		if((ch>='a' && ch<='z') ||
			(ch>='A' && ch<='Z')){
			return true;
		}
		return false;
	}
	
	public static boolean isBlank(char ch){
		if(ch==' ' || ch=='\t' ||
			ch=='\n' || ch=='\r'){
			return true;
		}
		return false;
	}
}
